using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace RpgServiceLib.Quest
{
	public class QuestFactory
	{
		protected virtual IQuestChangeAllowedStrategy questChangeAllowedStrategy {get;set;}
		protected virtual IQuestStatusHandlerStrategy questStatusHandlerStrategy{get;set;}
		protected virtual Dictionary<int,IQuest> listOfQuests{get;set;}
		protected virtual QuestEventHandlerManager eventHandler{ get; set; }
					
		public QuestFactory (IQuestChangeAllowedStrategy allow, IQuestStatusHandlerStrategy status, QuestEventHandlerManager eventHandler)
		{
			listOfQuests= new Dictionary<int, IQuest>();
			
			this.questChangeAllowedStrategy = allow;
			this.questStatusHandlerStrategy = status;
			this.eventHandler=eventHandler;
		}
		
		public IQuest GetQuestById(int id)
		{
			return listOfQuests[id];
		}

		public IEnumerable<IQuest> GetQuestByName (string name)
		{
			return 		from q in 
					listOfQuests.Values
						where q.NameOfQuest == name
						select q;
					     
		}

		protected virtual void WorkWithQuestGiveHimTheStrategy (IQuest quest)
		{
			listOfQuests.Add(quest.Id, quest);
			quest.changed+=eventHandler.FireChangeEvent;
			quest.SetQuestChangeAllowedStrategy(this.questChangeAllowedStrategy);
			quest.SetQuestStatusHandlerStrategy(this.questStatusHandlerStrategy);
		}
		
		public virtual IQuest CreateQueuedQuest(string name, string description, int id)
		{
			IQuest quest = new Quest(name, description, id);
			quest.SetQuestListType(QuestListType.ListIsQueue);
			WorkWithQuestGiveHimTheStrategy (quest);
			return quest;
		}

		public virtual IQuest CreateQueuedQuestNameAndDescIsComingFromFirstQuest (string name, string description, int id)
		{
			IQuest quest = new Quest (name, description, id);
			quest.SetQuestListType (QuestListType.ListIsQueueUseFirstTextAndDescriptionFromList);
			WorkWithQuestGiveHimTheStrategy (quest);
			return quest;
		}
				
		public virtual IQuest CreateParallelableQuest (string name, string description, int id)
		{
			IQuest quest = new Quest (name, description, id);
			quest.SetQuestListType (QuestListType.ListCanBeQuestedAtSameTime);
			WorkWithQuestGiveHimTheStrategy (quest);
			return quest;
		}		
	}
}

